CKYC Individual Download Docker Solution
API Description
Objective
A self-contained Docker package that enables Regulated Entities (REs) to integrate with CERSAI's CKYC APIs from their own infrastructure. As per CKYC guidelines v1.3, individual downloads require OTP-based consent.
OTP consent applies only to individual downloads.
This solution provides two APIs:
| API | Endpoint | Purpose |
|---|---|---|
| Start API | /api/v1/start | Initiates CKYC search and triggers OTP |
| Validate OTP and Download API | /api/v1/validateOtpAndDownload | Validates OTP and downloads CKYC data |
Start API /api/v1/start
Initiates a CKYC search and triggers an OTP to the user's registered mobile number.
API URL
http://localhost:8080/api/v1/start
Replace http://localhost:8080 with the RE's domain. For example: https://ckyc.hyperverge.co/api/v1/start
Method - POST
Authentication
You need a unique appId and appKey from HyperVerge to access this API.
Headers
| Header | Mandatory / Optional | Description | Input Format |
|---|---|---|---|
content-type | Mandatory | Defines the media type for the request payload. | application/json |
appId | Mandatory | The application ID shared by HyperVerge. You can find the details in the dashboard's credentials tab | This should be a unique value |
appKey | Mandatory | The application key shared by HyperVerge. You can find the details in the dashboard's credentials tab | This should be a unique value |
transactionId | Mandatory | A unique identifier for tracking a user journey | This should be both unique and easily associated with the user's journey in your application(s) |
Inputs
The following table provides the details of the parameters required for the /api/v1/start request body:
| Parameter | Mandatory / Optional | Type | Description | Input Format | Default Value | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
idNo | Mandatory | String | The ID number of the user. The accepted format depends on the idType value.Aadhaar (idType E) For idType E, pass idNo in the format: aadhaar|name|dob|gender | <Enter_the_ID_Number> | Not Applicable | ||||||||||||||||||||||||||||||
idType | Mandatory | String | The type of ID being submitted. Accepted values:
| <Enter_the_ID_Type> | Not Applicable | ||||||||||||||||||||||||||||||
entityType | Mandatory | String | Identifies the record as an individual. Must be passed for the HyperVerge API to correctly route the request. | individual | Not Applicable | ||||||||||||||||||||||||||||||
mobileNo | Mandatory for downloads; Optional when returnOnlySearchResponse is yes | String | The mobile number linked to the user's CKYC record. CERSAI verifies this before sending an OTP. If the number does not match or is not registered, the download cannot proceed. | <Enter_the_Mobile_Number> | Not Applicable | ||||||||||||||||||||||||||||||
returnOnlySearchResponse | Optional | String | If set to yes, only the search response is returned and OTP is not triggered. To proceed with a download after a search-only call, call /api/v1/start again with mobileNo. | yes / no | no | ||||||||||||||||||||||||||||||
returnckycRefNo | Optional | String | Returns the CKYC reference number in the ckycRefNo field of the response. | yes / no | no | ||||||||||||||||||||||||||||||
outputImageType | Optional | String | base64: returns images as Base64-encoded strings. selfurl: returns S3 presigned URLs (requires CLOUD_SERVICE=aws and S3_UPLOAD_URI). If not provided, imageDetails is returned as an empty list. | base64 / selfurl | Not Applicable |
Request
curl --location --request POST 'http://localhost:8080/api/v1/start' \
--header 'transactionId: <Enter_the_Transaction_ID>' \
--header 'appId: <Enter_the_App_ID>' \
--header 'appKey: <Enter_the_App_Key>' \
--header 'Content-Type: application/json' \
--data-raw '{
"idNo": "<Enter_the_ID_Number>",
"idType": "<Enter_the_ID_Type>",
"entityType": "individual",
"mobileNo": "<Enter_the_Mobile_Number>",
"returnOnlySearchResponse": "no",
"returnckycRefNo": "yes",
"outputImageType": "base64"
}'
Success Response
The following code snippets demonstrate success responses from the /api/v1/start:
- OTP Triggered
- Search Only
{
"status": "success",
"statusCode": "200",
"result": {
"message": "OTP has been sent to the registered mobile number XXXXXX1865",
"requestId": "<requestId>"
}
}
Set returnOnlySearchResponse: yes.mobileNo is not required and OTP is not triggered. To download after a search-only call, call /api/v1/start again with mobileNo.
{
"status": "success",
"statusCode": "200",
"result": {
"constitutionType": "",
"accountType": "",
"ckycNo": "XXXXXXXXXX7373",
"preFix": "",
"firstName": "",
"middleName": "",
"lastName": "",
"fullName": "",
"fatherOrSpouse": "",
"fatherPrefix": "",
"fatherFname": "",
"fatherMname": "",
"fatherLname": "",
"fatherFullName": "",
"motherPrefix": "",
"motherFname": "",
"motherMname": "",
"motherLname": "",
"motherFullName": "",
"gender": "",
"dob": "",
"age": "",
"address1": "",
"address2": "",
"address3": "",
"city": "",
"district": "",
"state": "",
"country": "",
"pincode": "",
"permAndCorresAddSame": "",
"corresAddress1": "",
"corresAddress2": "",
"corresAddress3": "",
"corresCity": "",
"corresDist": "",
"corresState": "",
"corresCountry": "",
"corresPin": "",
"resiStdCode": "",
"resiTelNo": "",
"mobileCode": "",
"mobileNumber": "",
"email": "",
"decDate": "",
"decPlace": "",
"kycDate": "********",
"updatedDate": "",
"idList": [
{ "STATUS": 3, "TYPE": "E" },
{ "STATUS": 3, "TYPE": "C" }
],
"corresPoa": "",
"poa": "",
"DocSub": "",
"kycName": "",
"kycDesignation": "",
"kycBranch": "",
"kycEmpCode": "",
"orgName": "",
"orgCode": "",
"officeStdCode": "",
"officeTelNo": "",
"numIdentity": "",
"numRelated": "",
"numImages": "",
"aadhaar": "",
"pan": "",
"formSixty": ""
}
}
In practice, CERSAI only returns the following fields for the search response:
ckycNo(masked)ckycRefNofullNamedobgenderagekycDateupdatedDateidList(type,status)
The full response structure is preserved for consistency with the download flow, reducing the need for any client-side transformation logic.
Success Response Details
The following table describes the key fields returned in the /api/v1/start success response:
| Parameter | Type | Description |
|---|---|---|
status | string | The status of the request. Returns success on a successful call. |
statusCode | string | The HTTP status code for the response. |
result.message | string | Confirmation that the OTP has been sent to the user's registered mobile number (masked). Returned when mobileNo is provided. |
result.requestId | string | A unique identifier for the OTP session. Must be passed to the Validate OTP and Download API. |
result.ckycNo | string | The CKYC number of the user (masked). Returned in the search-only response. |
result.fullName | string | The full name of the user as registered in CKYC. Returned in the search-only response. |
result.dob | string | Date of birth of the user. Returned in the search-only response. |
result.kycDate | string | The date on which the KYC was completed. Masked in the response (********). |
result.updatedDate | string | The date on which the KYC record was last updated. |
result.idList | array | List of ID types and their verification status associated with the CKYC record. |
result.ckycRefNo | string | The CKYC reference number. Returned only when returnckycRefNo is set to yes. |
Error Responses
The following are sample error responses for the /api/v1/start API:
CERSAI may update error response messages without prior notice. Treat the messages listed here as indicative; do not build logic that depends on their exact wording.
- Mobile Number Mismatch
- Mobile Number Not Registered
- Missing/Invalid Credentials
- No Record Found
- Digital Signature Error
- Server Error
{
"status": "failure",
"statusCode": "400",
"error": {
"code": "ER_REQ_VALIDATE",
"message": "Download failed. Auth Factor does not match that registered in the KYC record"
}
}
{
"status": "failure",
"statusCode": "400",
"error": {
"code": "ER_REQ_VALIDATE",
"message": "Download failed. Mobile number is not registered in the KYC record. Please download using bulk file methods"
}
}
{
"status": "failure",
"statusCode": "401",
"error": {
"code": "ER_AUTH",
"message": "Missing/Invalid credentials"
}
}
{
"status": "failure",
"statusCode": "404",
"error": {
"code": "ER_CKYC_SEARCH_AND_DOWNLOAD",
"message": "No record found"
}
}
{
"status": "failure",
"statusCode": "404",
"error": {
"code": "ER_CKYC_SEARCH_AND_DOWNLOAD",
"message": "Digital signature cannot be verified. The certificate is expired."
}
}
{
"status": "failure",
"statusCode": "500",
"error": {
"code": "ER_SERVER",
"message": "Internal server error"
}
}
Error Response Details
A failure response contains a failure status with a relevant status code and error message. The following table lists all error responses.
| Status Code | Error Message | Error Description | Error Resolution |
|---|---|---|---|
| 400 | Download failed. Auth Factor does not match that registered in the KYC record | The mobile number provided does not match the one linked to the user's CKYC record. | Verify the mobile number and retry. |
| 400 | Download failed. Mobile number is not registered in the KYC record. Please download using bulk file methods | No mobile number is linked to the user's CKYC record. OTP-based individual download is not possible. | Use bulk file download methods instead. |
| 401 | Missing/Invalid credentials | The request is missing or has invalid appId and appKey values. | Verify and provide valid appId and appKey credentials. |
| 404 | No record found | No CKYC record exists for the provided ID details. | Verify the idNo and idType and retry. |
| 404 | Digital signature cannot be verified. The certificate is expired. | The request XML failed digital signature verification on the CERSAI portal. Possible reasons: request XML signed with incorrect signature tag patterns; FI public and private keys do not match; expired digital signature certificate (DSC). | Check the signing configuration or contact HyperVerge support. |
| 500 | Internal Server Error | An unexpected error occurred on the server. | Contact HyperVerge support. |
Validate OTP and Download API validateOtpAndDownload
Use this API after collecting the OTP from the user to validate it and download the CKYC record.
API URL
http://localhost:8080/api/v1/validateOtpAndDownload
Replace http://localhost:8080 with the RE's domain where the CKYC services are hosted. For example: https://ckyc.hyperverge.co/api/v1/validateOtpAndDownload
Overview
The Validate OTP and Download API is RESTful and uses standard HTTP verbs and status codes. Responses are in JSON format. Send all parameters as JSON through a POST request.
Method - POST
Authentication
You need a unique pair of application ID (appId) and application key (appKey) from HyperVerge to access this API.
Headers
| Header | Mandatory / Optional | Description | Input Format |
|---|---|---|---|
content-type | Mandatory | Defines the media type for the request payload. | application/json |
appId | Mandatory | The application ID shared by HyperVerge. You can find the details in the dashboard's credentials tab | This should be a unique value |
appKey | Mandatory | The application key shared by HyperVerge. You can find the details in the dashboard's credentials tab | This should be a unique value |
transactionId | Mandatory | A unique identifier for tracking a user journey | This should be both unique and easily associated with the user's journey in your application(s) |
Inputs
The following table provides the details of the parameters required for the Validate OTP and Download API request body:
| Parameter | Mandatory / Optional | Type | Description | Input Format | Default Value |
|---|---|---|---|---|---|
otp | Mandatory | String | The OTP collected from the user. To trigger an OTP resend instead of validating, pass an empty string ("") and set retry to yes. | <Enter_the_OTP> | Not Applicable |
requestId | Mandatory | String | The unique request identifier returned in the /api/v1/start response. | <Enter_the_Request_ID> | Not Applicable |
entityType | Mandatory | String | Identifies the record as an individual. Must be passed for the HyperVerge API to correctly route the request. | individual | Not Applicable |
retry | Optional | String | Set to yes along with an empty otp to trigger an OTP resend. A minimum of 90 seconds must have elapsed since the last OTP request. Up to 3 resend attempts are allowed per session. | yes / no | no |
returnRecordCountDetails | Optional | String | Returns downloadCount and updateCount in the response. | yes / no | no |
returnckycRefNo | Optional | String | Returns the CKYC reference number in the ckycRefNo field of the response. | yes / no | no |
outputImageType | Optional | String | base64: returns images as Base64-encoded strings. selfurl: returns S3 presigned URLs (requires CLOUD_SERVICE=aws and S3_UPLOAD_URI). If not provided, imageDetails is returned as an empty list. | base64 / selfurl | Not Applicable |
returnResidentialStatus | Optional | String | If set to yes, adds residentialStatus and foreignNationalId to the response. | yes / no | no |
Request
curl --location --request POST 'http://localhost:8080/api/v1/validateOtpAndDownload' \
--header 'transactionId: <Enter_the_Transaction_ID>' \
--header 'appId: <Enter_the_App_ID>' \
--header 'appKey: <Enter_the_App_Key>' \
--header 'Content-Type: application/json' \
--data-raw '{
"otp": "<Enter_the_OTP>",
"requestId": "<Enter_the_Request_ID>",
"entityType": "individual",
"outputImageType": "base64",
"returnRecordCountDetails": "yes",
"returnckycRefNo": "yes",
"returnResidentialStatus": "yes"
}'
Success Response
The following code snippet demonstrates a success response from the Validate OTP and Download API:
{
"status": "success",
"statusCode": "200",
"result": {
"constitutionType": "Individual",
"accountType": "normal",
"ckycNo": "",
"preFix": "",
"firstName": "",
"middleName": "",
"lastName": "",
"fullName": "",
"fatherOrSpouse": "",
"fatherPrefix": "",
"fatherFname": "",
"fatherMname": "",
"fatherLname": "",
"fatherFullName": "",
"motherPrefix": "",
"motherFname": "",
"motherMname": "",
"motherLname": "",
"motherFullName": "",
"gender": "",
"dob": "",
"age": "",
"address1": "",
"address2": "",
"address3": "",
"city": "",
"district": "",
"state": "",
"country": "IN",
"pincode": "",
"permAndCorresAddSame": "Y",
"corresAddress1": "",
"corresAddress2": "",
"corresAddress3": "",
"corresCity": "",
"corresDist": "",
"corresState": "",
"corresCountry": "",
"corresPin": "",
"resiStdCode": "",
"resiTelNo": "",
"mobileCode": "", // available from v1.0.3
"mobileNumber": "", // available from v1.0.3
"email": "",
"decDate": "",
"decPlace": "",
"kycDate": "",
"updatedDate": "",
"idList": [],
"corresPoa": "",
"poa": "",
"DocSub": "",
"kycName": "",
"kycDesignation": "",
"kycBranch": "",
"kycEmpCode": "",
"orgName": "",
"orgCode": "",
"officeStdCode": "",
"officeTelNo": "",
"numIdentity": "",
"numRelated": "",
"numImages": "",
"aadhaar": "",
"pan": "",
"formSixty": "",
"imageDetails": [],
"disabilityFlag": false,
"disabilityType": 0,
"disabilityPercentage": 0,
"disabilityUuidNum": "",
"downloadCount": "",
"updateCount": "",
"ckycRefNo": "",
"residentialStatus": "",
"foreignNationalId": ""
}
}
Success Response Details
The following table describes the key fields returned in the Validate OTP and Download API success response:
| Parameter | Type | Description |
|---|---|---|
status | string | The status of the request. Returns success on a successful call. |
statusCode | string | The HTTP status code for the response. |
result.ckycNo | string | The CKYC number of the user. |
result.fullName | string | The full name of the user as registered in CKYC. |
result.dob | string | Date of birth of the user. |
result.gender | string | Gender of the user. |
result.address1, result.address2, result.address3 | string | Permanent address of the user split across three fields. |
result.kycDate | string | The date on which the KYC was completed. |
result.updatedDate | string | The date on which the KYC record was last updated. |
result.idList | array | List of ID types and their verification status associated with the CKYC record. |
result.imageDetails | array | List of images associated with the CKYC record. Returned in the format specified by outputImageType. Empty list if outputImageType is not provided. |
result.downloadCount | string | Total number of times this CKYC record has been downloaded. Returned only when returnRecordCountDetails is yes. |
result.updateCount | string | Total number of times this CKYC record has been updated. Returned only when returnRecordCountDetails is yes. |
result.ckycRefNo | string | The CKYC reference number. Returned only when returnckycRefNo is yes. |
result.residentialStatus | string | Residential status of the user. Returned only when returnResidentialStatus is yes. |
result.foreignNationalId | string | Foreign national ID of the user, if applicable. Returned only when returnResidentialStatus is yes. |
Error Responses
The following are sample error responses for the Validate OTP and Download API:
- Missing/Invalid Credentials
- Invalid OTP
- Resend Too Early
- Attempts Exhausted
- OTP Resend Success
- Server Error
{
"status": "failure",
"statusCode": "401",
"error": {
"code": "ER_AUTH",
"message": "Missing/Invalid credentials"
}
}
{
"status": "failure",
"statusCode": "404",
"error": {
"code": "ER_CKYC_SEARCH_AND_DOWNLOAD",
"message": "Invalid OTP entered. Remaining attempts: 2"
}
}
{
"status": "failure",
"statusCode": "404",
"error": {
"code": "ER_CKYC_SEARCH_AND_DOWNLOAD",
"message": "Resend OTP Option enable post 90 sec from the first request."
}
}
{
"status": "failure",
"statusCode": "404",
"error": {
"code": "ER_CKYC_SEARCH_AND_DOWNLOAD",
"message": "Download failed as OTP validation was unsuccessful"
}
}
{
"status": "failure",
"statusCode": "404",
"error": {
"code": "ER_CKYC_SEARCH_AND_DOWNLOAD",
"message": "Resend OTP Sent successfully to registered Mobile number XXXXXX8526 remaining attempts =1"
}
}
{
"status": "failure",
"statusCode": "500",
"error": {
"code": "ER_SERVER",
"message": "Internal server error"
}
}
Error Response Details
A failure response contains a failure status with a relevant status code and error message. The following table lists all error responses.
| Status Code | Error Message | Error Description | Error Resolution |
|---|---|---|---|
| 401 | Missing/Invalid credentials | The request is missing or has invalid appId and appKey values. | Verify and provide valid appId and appKey credentials. |
| 404 | Invalid OTP entered. Remaining attempts: <count> | The OTP entered is incorrect. 3 validation attempts are allowed per OTP generated. | Re-enter the correct OTP. The remaining attempts are shown in the error message. |
| 404 | Resend OTP Option enable post 90 sec from the first request. | A resend was attempted before the 90-second cooldown period had elapsed. | Wait 90 seconds after the last OTP request before retrying the resend. |
| 404 | Download failed as OTP validation was unsuccessful | All OTP validation attempts have been exhausted. The session is terminated. | Restart the process by calling /api/v1/start again. |
| 404 | Resend OTP Sent successfully to registered Mobile number XXXXXX<last4> remaining attempts =<count> | The OTP resend was successful. The remaining resend attempts are shown in the message. | Submit the new OTP via the Validate OTP and Download API. |
| 500 | Internal Server Error | An unexpected error occurred on the server. | Contact HyperVerge support. |